python 优先队列(基于二叉堆的实现)

您所在的位置:网站首页 优先级队列 python python 优先队列(基于二叉堆的实现)

python 优先队列(基于二叉堆的实现)

2024-01-19 18:39| 来源: 网络整理| 查看: 265

       普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。相同优先级的项则按照先进先出的顺序删除。优先队列的出队操作和队列一样,都是从队首出队,但在优先队列的内部,元素的次序却是由“优先级”来决定:高优先级的元素排在队首,而低优先级的元素则排在后面。这样,优先队列的入队操作就比较复杂,需要将元素根据优先级尽量排到队列前面。一个实现优先队列的经典方法便是采用二叉堆(Binary Heap)。二叉堆能将优先队列的入队和出队复杂度都保持在O(logn)。

一、二叉堆的结构性质

       平衡的二叉树根节点的左右子树的子节点个数相同。在堆的实现中,我们采用“完全二叉树”的结构来近似地实现“平衡”。完全二叉树,指每个内部节点树均达到最大值,除了最后一层可以只缺少右边的若干节点。下图所示就是一个完全二叉树。

       有意思的是使用单个列表就能实现完全树,不需要使用节点、引用或嵌套列表。因为对于完全二叉树,如果节点在列表中的下标为 p,那么其左子节点下标为 2p,右节点为 2p+1。当我们要找任何节点的父节点时,可以直接使用 python 的整除。如果节点在列表中下标为n,那么父节点下标为n//2。下图所示就是一个完全二叉树的列表表示法。

二、二叉堆操作的实现   

       二叉堆的有趣之处在于,其逻辑结构上像二叉树,却是用非嵌套的列表来实现。二叉堆有两种:键值总是最小的排在队首称为“最小堆(min heap)”,反之,键值总是最大的排在队首称为“最大堆(max heap)”。

       二叉堆的基本操作定义如下:

BinaryHeap():创建一个空的二叉堆对象 insert(k):将新元素加入到堆中 findMin():返回堆中的最小项,最小项仍保留在堆中 delMin():返回堆中的最小项,同时从堆中删除 isEmpty():返回堆是否为空 size():返回堆中节点的个数 buildHeap(list):从一个包含节点的列表里创建新堆

(1)创建二叉堆节点 

class BinHeap: def __init__(self): self.heapList = [0] self.currentSize = 0

(2)插入节点 

       为了满足“完全二叉树”的性质,新键值应该添加到列表的末尾。然而新键值简单地添加在列表末尾,显然无法满足堆次序。但我们可以通过比较父节点和新加入的元素的方法来重新满足堆次序。如果新加入的元素比父节点要小,可以与父节点互换位置。

def percUp(self,i): while i // 2 > 0: if self.heapList[i] < self.heapList[i // 2]: tmp = self.heapList[i // 2] self.heapList[i // 2] = self.heapList[i] self.heapList[i] = tmp i = i // 2 def insert(self,k): self.heapList.append(k) self.currentSize = self.currentSize + 1 self.percUp(self.currentSize)

(3)删除最小项

       堆次序(最小堆)要求根节点是树中最小的元素,因此很容易找到最小项。比较困难的是移走根节点的元素后如何保持堆结构和堆次序,我们可以分两步走。首先,用最后一个节点来代替根节点。移走最后一个节点保持了堆结构的性质。这么简单的替换,还是会破坏堆次序。那么第二步,将新节点“下沉”来恢复堆次序。图 4 所示的是一系列交换操作来使新节点“下沉”到正确的位置。

def percDown(self,i): while (i * 2) self.heapList[mc]: tmp = self.heapList[i] self.heapList[i] = self.heapList[mc] self.heapList[mc] = tmp i = mc def minChild(self,i): if i * 2 + 1 > self.currentSize: return i * 2 else: if self.heapList[i*2] < self.heapList[i*2+1]:


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3